package momo.multitree.structure;

import java.io.FileReader;

import momo.multitree.visual.TreeRenderApplication;
import junit.framework.TestCase;

public class TreeTest extends TestCase {

	private Tree tree;
	private Node root, node2, node3, node4, node5;
	
	private Edge edge1, edge2, edge3, edge4;
	
	protected void setUp() throws Exception {
		super.setUp();
		
		root = new Node("1", 0.5, 0.6); //root node
		node2 = new Node("2", 0.1, 0.3);
		node3 = new Node("3", 0.1, 0.8);
		node4 = new Node("4", 0.1, 0.4);
		node5 = new Node("5", 0.2, 0.9);
		
		edge1 = new Edge("1", root, node2, 5, 2, 6, 6);
		edge2 = new Edge("2", root, node3, 4, 3, 3, 3);
		edge3 = new Edge("3", node2, node4, 1, 7, 2, 2);
		edge4 = new Edge("4", node2, node5, 10, 0, 1, 1);
		
		tree = new Tree(root);
		tree.add(edge1);
		tree.add(edge2);
		tree.add(edge3);
		tree.add(edge4);
	}

	protected void tearDown() throws Exception {
		super.tearDown();
		tree = null;
	}
	
	public void testRemoveNode() {
		System.out.println("Current");
		tree.display();
		System.out.println("After removal of node2");
		tree.remove(node2);
		tree.display();
		System.out.println("After adding of new edge connecting 4-3 and 5-3");
		Edge e1 = new Edge("5", node3, node4, 1, 7, 2, 2);
		Edge e2 = new Edge("6", node3, node5, 10, 0, 1, 1); 
		tree.add(e1);
		tree.add(e2);
		tree.display();
	}
	
	public void testParentHood() {
		assertEquals(null, tree.getParent(root));
		assertEquals(root, tree.getParent(node2));
		assertEquals(root, tree.getParent(node3));
		assertEquals(node2, tree.getParent(node4));
		assertEquals(node2, tree.getParent(node5));
		
		tree.remove(edge1);
		assertEquals(null, tree.getParent(node2));
		Edge edge5 = new Edge("5", node3, node2, 100, 100, 100, 100); 
		tree.add(edge5, node3);
		assertEquals(node3, tree.getParent(node2));
		assertEquals(null, tree.getParent(root));
		assertEquals(root, tree.getParent(node3));
		assertEquals(node2, tree.getParent(node4));
		assertEquals(node2, tree.getParent(node5));
	}

	public void testCompWeightedLatency() {
		double expected = 11.1;
		double actual = tree.compWeightedLatency();
		assertEquals(expected, actual, 0.0000000000001);
	}
	
	public void testCompDecentWeightedLatency()
	{
		double expected = 9.1;
		double actual = tree.compDecentWeightedLatency();
		assertEquals(expected, actual, 0.0000000000001);
	}
	
	public void testCompStability()
	{
		double expected = 1.8;
		double actual = tree.compStability();
		assertEquals(expected, actual, 0.0000000000001);
	}
	
	public void testCompCost()
	{
		double expected = 19.3;
		double actual = tree.compCost();
		assertEquals(expected, actual, 0.0000000000001);
	}
	
//	public void testHasCycle()
//	{
//		Node nodeA = new Node(6, 1, 1);
//		Node nodeB = new Node(7, 1, 1);
//		
//		Edge edgeA = new Edge(1, root, nodeA, 1, 1, 1, 1);
//		Edge edgeB = new Edge(2, nodeA, nodeB, 1, 1, 1, 1);
//		Edge edgeC = new Edge(3, nodeB, root, 1, 1, 1, 1);
//		
//		tree.add(edgeA);
//		tree.add(edgeB);
//		tree.add(edgeC);
//		
//		assertTrue(tree.hasCycle(edgeB));
//	}
	
	public void testIsEdgeConnected()
	{
		
		Node root = new Node("1", 1, 1);
		Node nodeA = new Node("6", 1, 1);
		Node nodeB = new Node("7", 1, 1);
		
		Tree treeA = new Tree(root);
		
		Edge edge1 = new Edge("1", nodeB, root, 1, 1, 1, 1);
		assertTrue(treeA.isEdgeConnected(edge1));
		
		Edge edge2 = new Edge("2", nodeB, nodeA, 1, 1, 1, 1);
		assertTrue(!treeA.isEdgeConnected(edge2));
	}
	
	public void testOutput() throws Exception 
	{
		Node n1 = new Node("1", 0.08, 0.2);
		Node n2 = new Node("2", 0.06, 0.4);
		Node n3 = new Node("3", 0.06, 0.3);
		Node n4 = new Node("4", 0.05, 0.6);
		Node n5 = new Node("5", 0.6, 0.3);
		Node n6 = new Node("6", 0.1, 0.1);
		Node n7 = new Node("7", 0.05, 0.1);
		
		Node n8 = new Node("8", 0.05, 0.1);
		Node n9 = new Node("9", 0.05, 0.1);
		Node n10 = new Node("10", 0.05, 0.1);
		Node n11 = new Node("11", 0.05, 0.1);
		
		Edge e1 = new Edge("1", n1, n2, 1, 1, 1, 1);
		Edge e2 = new Edge("2", n1, n3, 2, 2, 2, 2);
		Edge e3 = new Edge("3", n1, n4, 3, 3, 3, 3);
		Edge e4 = new Edge("4", n4, n5, 4, 4, 4, 4);
		Edge e5 = new Edge("5", n4, n6, 5, 5, 5, 5);
		Edge e6 = new Edge("6", n6, n7, 6, 6, 6, 6);
		Edge e7 = new Edge("7", n7, n8, 7, 7, 7, 7);
		Edge e8 = new Edge("8", n7, n9, 8, 8, 8, 8);
		Edge e9 = new Edge("9", n7, n10, 9, 9, 9, 9);
		Edge e10 = new Edge("10", n7, n11, 10, 10, 10, 10);
		
		Tree tree = new Tree(n1);
		tree.add(e1);
		tree.add(e2);
		tree.add(e3);
		
		tree.add(e5);
		tree.add(e4);
		
		tree.add(e6);
		tree.add(e7);
		tree.add(e8);
		tree.add(e9);
		tree.add(e10);
		
//		tree.outputVisual("jack");
	}
	
	public void testConstructorBasedOnFile()
	{
		Node n1 = new Node("1", 0.08, 0.2);
		Node n2 = new Node("2", 0.06, 0.4);
		Node n3 = new Node("3", 0.06, 0.3);
		Node n4 = new Node("4", 0.05, 0.6);
		Node n5 = new Node("5", 0.6, 0.3);
		Node n6 = new Node("6", 0.1, 0.1);
		Node n7 = new Node("7", 0.05, 0.1);
		
		Node n8 = new Node("8", 0.05, 0.1);
		Node n9 = new Node("9", 0.05, 0.1);
		Node n10 = new Node("10", 0.05, 0.1);
		Node n11 = new Node("11", 0.05, 0.1);
		
		Edge e1 = new Edge("1", n1, n2, 1, 1, 1, 1);
		Edge e2 = new Edge("2", n1, n3, 2, 2, 2, 2);
		Edge e3 = new Edge("3", n1, n4, 3, 3, 3, 3);
		Edge e4 = new Edge("4", n4, n5, 4, 4, 4, 4);
		Edge e5 = new Edge("5", n4, n6, 5, 5, 5, 5);
		Edge e6 = new Edge("6", n6, n7, 6, 6, 6, 6);
		Edge e7 = new Edge("7", n7, n8, 7, 7, 7, 7);
		Edge e8 = new Edge("8", n7, n9, 8, 8, 8, 8);
		Edge e9 = new Edge("9", n7, n10, 9, 9, 9, 9);
		Edge e10 = new Edge("10", n7, n11, 10, 10, 10, 10);
		
		Tree tree1 = new Tree(n1);
		tree1.add(e1);
		tree1.add(e2);
		tree1.add(e3);
		
		tree1.add(e5);
		tree1.add(e4);
		
		tree1.add(e6);
		tree1.add(e7);
		tree1.add(e8);
		tree1.add(e9);
		tree1.add(e10);
		
//		try
//		{
//			String filename = "5_node_symmetric_dataset_1_TREE.txt";
//			tree1.outputDatasetFile(filename);
//			tree1.outputVisual("tree1_visual");
//			
//			Tree tree2 = new Tree(new FileReader(filename));
//			tree2.outputVisual("tree2_visual");
//			assertTrue(tree1.compare(tree2));
//		}catch(Exception e)
//		{
//			e.printStackTrace();
//		}
	}
	
	public void testChangeRoot()
	{
		Node[] nodes = new Node[11];
		
		nodes[0] = new Node("0", 0.08, 0.2);
		nodes[1] = new Node("1", 0.06, 0.4);
		nodes[2] = new Node("2", 0.06, 0.3);
		nodes[3] = new Node("3", 0.05, 0.6);
		nodes[4] = new Node("4", 0.6, 0.3);
		nodes[5] = new Node("5", 0.1, 0.1);
		nodes[6] = new Node("6", 0.05, 0.1);
		
		nodes[7] = new Node("7", 0.05, 0.1);
		nodes[8] = new Node("8", 0.05, 0.1);
		nodes[9] = new Node("9", 0.05, 0.1);
		nodes[10] = new Node("10", 0.05, 0.1);
		
		Edge e1 = new Edge("1", nodes[0], nodes[1], 1, 1, 1, 1);
		Edge e2 = new Edge("2", nodes[0], nodes[2], 2, 2, 2, 2);
		Edge e3 = new Edge("3", nodes[0], nodes[3], 3, 3, 3, 3);
		Edge e4 = new Edge("4", nodes[3], nodes[4], 4, 4, 4, 4);
		Edge e5 = new Edge("5", nodes[3], nodes[5], 5, 5, 5, 5);
		Edge e6 = new Edge("6", nodes[5], nodes[6], 6, 6, 6, 6);
		Edge e7 = new Edge("7", nodes[6], nodes[7], 7, 7, 7, 7);
		Edge e8 = new Edge("8", nodes[6], nodes[8], 8, 8, 8, 8);
		Edge e9 = new Edge("9", nodes[6], nodes[9], 9, 9, 9, 9);
		Edge e10 = new Edge("10", nodes[6], nodes[10], 10, 10, 10, 10);
		
		Tree t = new Tree(nodes[0]);
		t.add(e1);
		t.add(e2);
		t.add(e3);
		
		t.add(e5);
		t.add(e4);
		
		t.add(e6);
		t.add(e7);
		t.add(e8);
		t.add(e9);
		t.add(e10);
		
//		try
//		{
//			for(int i=0; i<nodes.length; i++)
//			{
//				t.changeRoot(nodes[i]);
//				t.outputVisual("node["+i+"]_as_root");
//			}
//		}catch(Exception e)
//		{
//			e.printStackTrace();
//		}
	}
	
	public void testRemoveEdge()
	{
		Node[] nodes = new Node[4];
		for(int i=0; i<nodes.length; i++)
			nodes[i] = new Node(""+i, 1, 1);
		
		Edge e1 = new Edge("1", nodes[0], nodes[1], 1, 1, 1, 1);
		Edge e2 = new Edge("2", nodes[2], nodes[1], 1, 1, 1, 1);
		Edge e3 = new Edge("3", nodes[3], nodes[2], 1, 1, 1, 1);
		
		Tree t = new Tree(nodes[0]);
		t.add(e1);
		t.add(e2);
		t.add(e3);
		
//		System.out.println("\nOrginial");
//		t.display();
//		t.remove(e3);
//		System.out.println("\nAfter removal");
//		t.display();
//		t.add(e3);
//		System.out.println("\nAfter add back");
//		t.display();
	}
	
}//end of class TreeTest
